﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common.Model;
using System.Windows.Forms;
using JOthello.Forms;
using Common.Extensions;
using JOthello.FB;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Diagnostics;

namespace JOthello.Controls
{
    public class MainControl
    {
        private static readonly String kMenschSpieler = "Mensch";
        private static readonly String kComputerSpieler = "Computer";
        private static readonly String kMultiplayer = "Multiplayer";
        private List<CSpieler> sps = new List<CSpieler>();
        private CSpieler CurrentSpieler = new CSpieler()
        {
            Farbe = CSpielfeld.FieldColor.Black
        };

        #region getter / setter
        public MainForm MainForm { get; set; }
        #endregion

        #region konstruktor
        public MainControl(MainForm f, string[] args)
        {
            MainForm = f;
            setup();

            if (args.Count() == 1 && File.Exists(args[0]))
            {
                (new SpielForm(args[0])).ShowDialog();
            }
        }
        #endregion

        public void setup()
        {
            setupCboSpielerType();
            setupTrkDifficult();

            MainForm.NudFieldSize.Value = Properties.Settings.Default.FieldSize;
            MainForm.NudFieldSize.ValueChanged += (s, e) => checkFieldSize();

            MainForm.ChkPossibleMoves.Checked = Properties.Settings.Default.ShowPossible;

            MainForm.TrkGameMode.Value = Properties.Settings.Default.DefaultMode;

            MainForm.PbxSpielerBild.Image = CurrentSpieler.Bild.Resize(MainForm.PbxSpielerBild.Height, (CurrentSpieler.Bild.Height / CurrentSpieler.Bild.Width) * MainForm.PbxSpielerBild.Height);

            MainForm.BtnLetsGo.Visible =
                MainForm.TrkGameMode.Visible =
                MainForm.LblGamemodeDefault.Visible =
                MainForm.LblGamemodeReversi.Visible =
                MainForm.LblFieldSize.Visible =
                MainForm.NudFieldSize.Visible =
                MainForm.ChkPossibleMoves.Visible = 
                false;

            MainForm.BtnComputerAdd.Click += new EventHandler(btnComputerAdd_Click);
            MainForm.BtnSpielerAdd.Click += new EventHandler(btnSpielerAdd_Click);
            MainForm.PbxSpielerBild.Click += new EventHandler(pbxSpielerBild_Click);
            MainForm.BtnFacebook.Click += new EventHandler(btnFacebook_Click);
            MainForm.BtnLetsGo.Click += new EventHandler(btnLetsGo_Click);

            MainForm.DgvSpielerAll.RowsAdded += (s, e) => remakeGrid();
            MainForm.DgvSpielerAll.RowsRemoved += new DataGridViewRowsRemovedEventHandler(dgvSpielerAll_RowsRemoved);

            MainForm.BtnImport.Click += new EventHandler(BtnImport_Click);
        }

        public void setupCboSpielerType()
        {
            MainForm.CboSpielerTyp.Items.Clear();
            MainForm.CboSpielerTyp.Items.Add(kMenschSpieler);
            MainForm.CboSpielerTyp.Items.Add(kComputerSpieler);
            MainForm.CboSpielerTyp.Items.Add(kMultiplayer);
            MainForm.CboSpielerTyp.SelectedIndexChanged += new EventHandler(cboSpielerTyp_SelectedIndexChanged);
            MainForm.CboSpielerTyp.SelectedIndex = 0;
        }
        public void setupTrkDifficult()
        {
            MainForm.TrkDifficult.Value = MainForm.TrkDifficult.Minimum = 0;
            MainForm.TrkDifficult.Maximum = Enum.GetNames(typeof(CKISpieler.Level)).Length - 1;
            trkDifficult_Scroll(MainForm.TrkDifficult, null);
            MainForm.TrkDifficult.Scroll += new EventHandler(trkDifficult_Scroll);
        }

        #region events
        private void trkDifficult_Scroll(object sender, EventArgs e)
        {
            MainForm.LblDifficult.Text = ((CKISpieler.Level)MainForm.TrkDifficult.Value).ToString();
        }
        private void cboSpielerTyp_SelectedIndexChanged(object sender, EventArgs e)
        {
            ComboBox s = sender as ComboBox;
            if (s != null)
            {
                remakeVisibility(s.SelectedItem);
            }
        }

        private void BtnImport_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog()
            {
                Multiselect = false,
                Title = "JOthello Spiel",
                Filter = "JOthello Spiel|*" + CProtokoll.suffix,
                CheckFileExists = true,
                CheckPathExists = true
            };
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    (new SpielForm(ofd.FileName)).ShowDialog();
                }
                catch (Exception ex)
                {
                    Debug.Print(ex.StackTrace);
                }
            }
        }

        private void btnLetsGo_Click(object sender, EventArgs e)
        {
            if (!checkFieldSize()) return;

            bool haveToSave = false;
            if (Properties.Settings.Default.FieldSize != (int)MainForm.NudFieldSize.Value)
            {
                Properties.Settings.Default.FieldSize = (int)MainForm.NudFieldSize.Value;
                haveToSave = true;
            }

            if (Properties.Settings.Default.ShowPossible != MainForm.ChkPossibleMoves.Checked)
            {
                Properties.Settings.Default.ShowPossible = MainForm.ChkPossibleMoves.Checked;
                haveToSave = true;
            }

            if (Properties.Settings.Default.DefaultMode != MainForm.TrkGameMode.Value)
            {
                Properties.Settings.Default.DefaultMode = MainForm.TrkGameMode.Value;
                haveToSave = true;
            }

            if (haveToSave) Properties.Settings.Default.Save();

            (new SpielForm(sps, (CSpielfeld.GameMode)MainForm.TrkGameMode.Value, (int)MainForm.NudFieldSize.Value, MainForm.ChkPossibleMoves.Checked)).ShowDialog();
        }

        private void btnFacebook_Click(object sender, EventArgs e)
        {
            Forms.FB.FacebookLoginForm fbLoginForm = new Forms.FB.FacebookLoginForm();
            if (fbLoginForm.ShowDialog() == DialogResult.OK)
            {
                FBHelper.reLoadBildAsync(FBLoaded);
                MainForm.TxtSpielerName.Text = "Informationen holen...";
            }
        }

        private void dgvSpielerAll_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
        {
            try
            {
                sps.RemoveAt(e.RowIndex);
                remakeGrid();
            }
            catch (Exception)
            {
                throw;
            }
        }

        private void btnComputerAdd_Click(object sender, EventArgs e)
        {
            CurrentSpieler = new CKISpieler(CSpielfeld.FieldColor.Black, ((CKISpieler.Level)MainForm.TrkDifficult.Value), "Computer");
            addSpieler(true);
        }

        private void btnSpielerAdd_Click(object sender, EventArgs e)
        {
            CurrentSpieler.Name = MainForm.TxtSpielerName.Text;

            if (MainForm.CboSpielerTyp.SelectedItem.ToString() == kMultiplayer)
            {
                (new MultiplayerForm(CurrentSpieler)).ShowDialog();
                return;
            }

            addSpieler(false);
        }

        private void pbxSpielerBild_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Bild|*.bmp;*.jpg;*.jpeg;*.png;*gif";
            if (ofd.ShowDialog() == DialogResult.OK && File.Exists(ofd.FileName))
            {
                CurrentSpieler.Bild = Image.FromFile(ofd.FileName) as Bitmap;
                MainForm.PbxSpielerBild.Image = resizeForPictureBox(CurrentSpieler.Bild);
            }
            ofd.Dispose();
        }
        #endregion

        private void addSpieler(Boolean isKI)
        {
            if (sps.Count == 1) CurrentSpieler.Farbe = (CSpielfeld.FieldColor)(((int)sps.First().Farbe) * -1);
            sps.Add(CurrentSpieler);

            if (isKI)
                MainForm.DgvSpielerAll.Rows.Add(new object[] { CurrentSpieler.Bild.Resize(50, 50), CurrentSpieler.Name, "", ((CKISpieler)CurrentSpieler).level });
            else
                MainForm.DgvSpielerAll.Rows.Add(new object[] { CurrentSpieler.Bild.Resize(50, 50), CurrentSpieler.Name, "", "Werden wir sehen :)" });

            DataGridViewCell cell = MainForm.DgvSpielerAll.Rows[MainForm.DgvSpielerAll.Rows.Count - 1].Cells[2];
            cell.Style.BackColor = cell.Style.SelectionBackColor = CurrentSpieler.Farbe == CSpielfeld.FieldColor.Black ? Color.Black : Color.WhiteSmoke;

            CurrentSpieler = new CSpieler()
            {
                Farbe = CSpielfeld.FieldColor.Black
            };
            MainForm.TxtSpielerName.Text = CurrentSpieler.Name;
            MainForm.PbxSpielerBild.Image = resizeForPictureBox(CurrentSpieler.Bild);
        }

        private void FBLoaded()
        {
            CurrentSpieler.Bild = FBHelper.Bild;
            MainForm.TxtSpielerName.Text = CurrentSpieler.Name = FBHelper.Fullname;
            MainForm.PbxSpielerBild.Image = resizeForPictureBox(CurrentSpieler.Bild);
        }

        private Bitmap resizeForPictureBox(Bitmap bmp)
        {
            return bmp.Resize((int)(((double)bmp.Width) / ((double)bmp.Height) * MainForm.PbxSpielerBild.Height), MainForm.PbxSpielerBild.Height);
        }

        private void remakeVisibility(object selected)
        {
            if (selected.ToString() == kComputerSpieler)
            {
                MainForm.BtnFacebook.Visible =
                    MainForm.PbxSpielerBild.Visible =
                    MainForm.TxtSpielerName.Visible =
                    MainForm.BtnSpielerAdd.Visible =
                    MainForm.LblFieldSize.Visible =
                    MainForm.NudFieldSize.Visible =
                    MainForm.ChkPossibleMoves.Visible = 
                    false;

                MainForm.TrkDifficult.Visible =
                    MainForm.LblDifficult.Visible =
                    MainForm.BtnComputerAdd.Visible =
                    true;
            }
            else if (selected.ToString() == kMenschSpieler)
            {
                MainForm.BtnFacebook.Visible =
                    MainForm.PbxSpielerBild.Visible =
                    MainForm.TxtSpielerName.Visible =
                    MainForm.BtnSpielerAdd.Visible =
                    true;

                MainForm.TrkDifficult.Visible =
                    MainForm.LblDifficult.Visible =
                    MainForm.BtnComputerAdd.Visible =
                    MainForm.LblFieldSize.Visible =
                    MainForm.NudFieldSize.Visible =
                    MainForm.ChkPossibleMoves.Visible = 
                    false;
            }

            else if (selected.ToString() == kMultiplayer)
            {
                MainForm.BtnFacebook.Visible =
                    MainForm.PbxSpielerBild.Visible =
                    MainForm.TxtSpielerName.Visible =
                    MainForm.BtnSpielerAdd.Visible =
                    true;

                MainForm.TrkDifficult.Visible =
                    MainForm.LblDifficult.Visible =
                    MainForm.BtnComputerAdd.Visible =
                    MainForm.LblFieldSize.Visible =
                    MainForm.NudFieldSize.Visible =
                    MainForm.ChkPossibleMoves.Visible = 
                    false;
            }
        }

        private void remakeGrid()
        {
            if (MainForm.DgvSpielerAll.Rows.Count == 2)
            {
                MainForm.BtnFacebook.Visible =
                    MainForm.BtnSpielerAdd.Visible =
                    MainForm.LblDifficult.Visible =
                    MainForm.BtnComputerAdd.Visible =
                    MainForm.CboSpielerTyp.Visible =
                    MainForm.PbxSpielerBild.Visible =
                    MainForm.TxtSpielerName.Visible =
                    MainForm.TrkDifficult.Visible =
                    false;

                MainForm.BtnLetsGo.Visible =
                    MainForm.TrkGameMode.Visible =
                    MainForm.LblGamemodeDefault.Visible =
                    MainForm.LblGamemodeReversi.Visible =
                    MainForm.LblFieldSize.Visible =
                    MainForm.NudFieldSize.Visible =
                    MainForm.ChkPossibleMoves.Visible = 
                    true;
            }
            else
            {
                MainForm.CboSpielerTyp.Visible = true;
                MainForm.BtnLetsGo.Visible =
                    MainForm.TrkGameMode.Visible =
                    MainForm.LblGamemodeDefault.Visible =
                    MainForm.LblGamemodeReversi.Visible =
                    MainForm.LblFieldSize.Visible =
                    MainForm.NudFieldSize.Visible =
                    MainForm.ChkPossibleMoves.Visible = 
                    false;

                remakeVisibility(MainForm.CboSpielerTyp.SelectedItem);
            }

            MainForm.DgvSpielerAll.AutoResizeRows();
            MainForm.DgvSpielerAll.AutoResizeColumns();
        }

        private bool checkFieldSize()
        {
            if (MainForm.NudFieldSize.Value % 2 != 0 || MainForm.NudFieldSize.Value > 20 || MainForm.NudFieldSize.Value < 4)
            {
                MessageBox.Show("Die Spielfeldgrösse muss eine gerade Zahl sein und sie muss zwischen 4 und 20 liegen.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
                MainForm.NudFieldSize.Value = Properties.Settings.Default.FieldSize;
                return false;
            }
            return true;

        }
    }
}
